import { _decorator, ccenum, CCFloat, Component, game, macro, Node, Vec3, v3 } from 'cc';
import { ActorManager } from '../level/ActorManager';
import { StateDefine } from './StateDefine';
import { Actor } from './Actor';
import { ProjectileEmitter } from './ProjectileEmitter';
import { PlayerController } from './PlayerController';
const { ccclass, property, requireComponent } = _decorator;

export enum Career{
    Melee = 0,
    Range = 1,
}

ccenum(Career)


let hurtDirection = v3();


@ccclass('EnemyController')
@requireComponent(Actor)
export class EnemyController extends Component {

    actor:Actor = null;

    @property(CCFloat)
    attackRange: number = 0.5;

    @property(CCFloat)
    attackInterval: number = 5;

    lastAttackTime: number = 0;

    @property({type: Career})
    career:Career = Career.Melee;

    projectileEmitter: ProjectileEmitter;

    @property(Node)
    projectileStartNode:Node = null;

    target:Actor = null;

    start() {
        this.actor = this.node.getComponent(Actor);

        this.node.on("onFrameAttack", this.onFrameAttack, this);

        this.schedule(this.executeAI, 1.0, macro.REPEAT_FOREVER ,1.0)

        if(this.career == Career.Range){
            this.projectileEmitter = this.node.getComponent(ProjectileEmitter);
        }

        this.target = ActorManager.instance.playActor;
    }

    onDestroy(){
        this.unschedule(this.executeAI);
        this.node.off("onFrameAttack", this.onFrameAttack, this);
    }

    executeAI(){
        // 判断玩家是否存在，是否可攻击
        if(!this.target){
            return;
        }
            
        // 我不处于 Run/Idle 状态
        if (this.actor.currState != StateDefine.Idle && this.actor.currState != StateDefine.Run) 
            return;

        const canAttack = game.totalTime - this.lastAttackTime >= this.attackInterval;

        // 目标已死或我不能攻击
        if (this.target.currState == StateDefine.Die || !canAttack) {
            this.actor.changeState(StateDefine.Idle);
            return;
        }

        // 限定攻击范围
        const distance = Vec3.distance(this.node.worldPosition, this.target.node.worldPosition);

        Vec3.subtract(this.actor.input, this.target.node.worldPosition, this.node.worldPosition);
        this.actor.input.normalize();
        this.actor.input.y = 0;

        if(distance > this.attackRange){
            this.actor.changeState(StateDefine.Run);
            return;
        }else{
            this.actor.input.set(0, 0, 0);
        }

        this.lastAttackTime = game.totalTime;
        this.actor.changeState(StateDefine.Attack);

    }

    onFrameAttack(){
        if(!this.target || this.target.currState == StateDefine.Die)
            return;

        Vec3.subtract(hurtDirection,  this.target.node.worldPosition, this.node.worldPosition);
        let distance = hurtDirection.length();
        // 攻击范围判定
        if(distance < this.attackRange){
            hurtDirection.normalize();
            Vec3.subtract(this.actor.input, this.target.node.worldPosition, this.node.worldPosition);
            this.actor.input.normalize();
            this.actor.input.y = 0;
            // 1.近战 直接伤害
            if(this.career == Career.Melee){
                // 攻击角度【如果在正前方 180度视角范围内】
                const angle = Vec3.angle(hurtDirection, this.node.forward);
                if(angle < Math.PI){
                    this.target.hurt(this.actor.actorProperty.attack, hurtDirection, this.actor);
                }
            }

            // 2.远程法师 使用发射器
            if(this.career == Career.Range){
                let projectile = this.projectileEmitter.create();
                projectile.node.forward = hurtDirection
                const scale = this.actor.node.scale.x / 2;
                projectile.node.setWorldScale(scale, scale, scale);
                projectile?.fire();
                projectile.host = this.node;
                projectile.node.worldPosition = this.projectileStartNode.worldPosition;
            }
        }

       
    }
}

